package webserver.bank;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import std.bank.Bank;
import std.bank.BankImpl;

public class GenericClassCallerImpl implements GenericClassCaller
{
	public static void main(String args[]) throws SecurityException,
			IllegalArgumentException, ClassNotFoundException,
			NoSuchMethodException, IllegalAccessException,
			InvocationTargetException
	{
		String[] parameters = { "allan" };
		String[] parameterTypes = { "java.lang.String" };
		Bank bank = new BankImpl();

		GenericClassCallerImpl th = new GenericClassCallerImpl();
		System.out.println(th.callClass(bank, "getAccount", parameters,
				parameterTypes));
	}

	public Object callClass(Object object, String method, Object parameters[],
			String[] parameterTypes) throws ClassNotFoundException,
			SecurityException, NoSuchMethodException, IllegalArgumentException,
			IllegalAccessException, InvocationTargetException
	{
		if (parameterTypes == null)
		{
			Class<?> thisClass = Class.forName(object.getClass().getName());
			Method thisMethod = thisClass.getDeclaredMethod(method);
			return thisMethod.invoke(object, parameters);
		}
		else
		{
			Class<?> params[] = new Class[parameterTypes.length];
			for (int i = 0; i < parameterTypes.length; i++)
			{
				if (parameterTypes[i].startsWith("int"))
					params[i] = int.class;
				else if (parameterTypes[i].startsWith("byte"))
					params[i] = byte.class;
				else if (parameterTypes[i].startsWith("short"))
					params[i] = short.class;
				else if (parameterTypes[i].startsWith("long"))
					params[i] = long.class;
				else if (parameterTypes[i].startsWith("char"))
					params[i] = char.class;
				else if (parameterTypes[i].startsWith("float"))
					params[i] = float.class;
				else if (parameterTypes[i].startsWith("double"))
					params[i] = double.class;
				else if (parameterTypes[i].startsWith("boolean"))
					params[i] = boolean.class;
				else
					params[i] = Class.forName(parameterTypes[i]);
			}

			Class<?> thisClass = Class.forName(object.getClass().getName());
			Method thisMethod = thisClass.getDeclaredMethod(method, params);
			return thisMethod.invoke(object, parameters);
		}
	}
}
